package com.mcppro.aidatabase.service;

import com.mcppro.aidatabase.dto.ChatDto;
import com.mcppro.aidatabase.dto.DatabaseOperationResult;
import com.mcppro.aidatabase.dto.IntentDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * AI聊天服务
 * 整合意图解析、数据库操作和AI响应生成
 * 
 * @author MCP Pro
 */
@Service
@Slf4j
public class AiChatService {

    private final IntentAnalysisService intentAnalysisService;
    private final DatabaseOperationService databaseOperationService;
    private final SiliconFlowService siliconFlowService;
    private final ChatLogService chatLogService;

    @Autowired
    public AiChatService(IntentAnalysisService intentAnalysisService,
                         DatabaseOperationService databaseOperationService,
                         SiliconFlowService siliconFlowService,
                         ChatLogService chatLogService) {
        this.intentAnalysisService = intentAnalysisService;
        this.databaseOperationService = databaseOperationService;
        this.siliconFlowService = siliconFlowService;
        this.chatLogService = chatLogService;
    }

    /**
     * 处理用户聊天请求
     * 
     * @param request 聊天请求
     * @return 聊天响应
     */
    public Mono<ChatDto.ChatResponse> processChat(ChatDto.ChatRequest request) {
        long startTime = System.currentTimeMillis();
        String sessionId = request.getSessionId() != null ? request.getSessionId() : UUID.randomUUID().toString();
        
        log.info("处理聊天请求 - 会话ID: {}, 问题: {}", sessionId, request.getQuestion());
        
        return intentAnalysisService.analyzeIntent(request.getQuestion())
                .flatMap(intent -> {
                    log.debug("意图解析完成 - 操作类型: {}, 置信度: {}", intent.getOperation(), intent.getConfidence());
                    
                    // 检查意图是否有效
                    if (!intentAnalysisService.isValidIntent(intent)) {
                        return handleUnknownIntent(request.getQuestion(), sessionId, intent);
                    }
                    
                    // 执行数据库操作
                    DatabaseOperationResult dbResult = databaseOperationService.executeOperation(intent);
                    
                    // 生成AI响应
                    return generateAiResponse(request.getQuestion(), intent, dbResult)
                            .map(aiResponse -> {
                                ChatDto.ChatResponse response = ChatDto.ChatResponse.success(aiResponse, dbResult, sessionId);
                                if (request.isIncludeDetails()) {
                                    response.setIntentResult(intent);
                                }
                                response.setTotalExecutionTime(System.currentTimeMillis() - startTime);
                                
                                // 异步记录日志
                                chatLogService.logChatInteraction(sessionId, request.getQuestion(), intent, dbResult, aiResponse);
                                
                                return response;
                            });
                })
                .onErrorResume(error -> {
                    log.error("聊天处理失败", error);
                    ChatDto.ChatResponse errorResponse = ChatDto.ChatResponse.failure(
                            "处理请求时发生错误: " + error.getMessage(), 
                            sessionId
                    );
                    errorResponse.setTotalExecutionTime(System.currentTimeMillis() - startTime);
                    
                    // 记录错误日志
                    chatLogService.logErrorInteraction(sessionId, request.getQuestion(), error.getMessage());
                    
                    return Mono.just(errorResponse);
                });
    }

    /**
     * 处理未知意图
     */
    private Mono<ChatDto.ChatResponse> handleUnknownIntent(String question, String sessionId, IntentDto.IntentResult intent) {
        log.warn("无法理解用户意图 - 问题: {}, 置信度: {}", question, intent.getConfidence());
        
        String systemPrompt = """
                你是一个数据库管理助手，用户的问题你无法理解其数据库操作意图。
                请礼貌地告诉用户你无法理解他们的问题，并提供一些示例问题来帮助他们。
                
                示例问题：
                - "查询所有用户"
                - "查找年龄大于25岁的用户"
                - "添加一个新用户，用户名是testuser，邮箱是test@example.com"
                - "更新用户名为zhangsan的用户年龄为30"
                - "删除状态为INACTIVE的用户"
                - "统计活跃用户数量"
                
                请用友好的语气回复。
                """;
        
        return siliconFlowService.chat(question, systemPrompt)
                .map(aiResponse -> {
                    ChatDto.ChatResponse response = new ChatDto.ChatResponse();
                    response.setSuccess(false);
                    response.setMessage(aiResponse);
                    response.setSessionId(sessionId);
                    response.setTimestamp(System.currentTimeMillis());
                    return response;
                })
                .onErrorReturn(ChatDto.ChatResponse.failure("抱歉，我无法理解您的问题。请尝试提问关于用户数据的查询、添加、更新或删除操作。", sessionId));
    }

    /**
     * 生成AI响应
     */
    private Mono<String> generateAiResponse(String userQuestion, IntentDto.IntentResult intent, DatabaseOperationResult dbResult) {
        if (!dbResult.isSuccess()) {
            return Mono.just("抱歉，执行您的请求时遇到了问题：" + dbResult.getErrorMessage());
        }
        
        String systemPrompt = """
                你是一个专业的数据库管理助手。用户向你提出了一个数据库操作请求，你已经成功执行了相应的数据库操作。
                现在请你根据操作结果，用自然、友好的语言向用户汇报执行结果。
                
                要求：
                1. 语言要自然、友好、专业
                2. 如果是查询操作，要总结查询结果的关键信息
                3. 如果是增删改操作，要确认操作结果
                4. 如果查询结果为空，要礼貌地说明
                5. 避免直接展示SQL语句或技术细节
                6. 用中文回复
                """;
        
        String operationSummary = buildOperationSummary(intent, dbResult);
        String userPrompt = String.format("""
                用户问题：%s
                
                数据库操作结果：
                %s
                
                请根据以上信息生成一个友好的回复。
                """, userQuestion, operationSummary);
        
        return siliconFlowService.chat(userPrompt, systemPrompt)
                .onErrorReturn("操作已完成。" + getDefaultResponseMessage(intent, dbResult));
    }

    /**
     * 构建操作摘要
     */
    private String buildOperationSummary(IntentDto.IntentResult intent, DatabaseOperationResult dbResult) {
        StringBuilder summary = new StringBuilder();
        summary.append("操作类型：").append(getOperationDescription(intent.getOperation())).append("\n");
        summary.append("执行状态：").append(dbResult.isSuccess() ? "成功" : "失败").append("\n");
        
        if (dbResult.isSuccess()) {
            switch (intent.getOperation()) {
                case SELECT, COUNT -> {
                    if (dbResult.getData() != null) {
                        summary.append("查询结果数量：").append(dbResult.getData().size()).append("条\n");
                        if (!dbResult.getData().isEmpty()) {
                            summary.append("查询结果示例：\n");
                            // 只显示前3条结果的摘要
                            int limit = Math.min(3, dbResult.getData().size());
                            for (int i = 0; i < limit; i++) {
                                Map<String, Object> row = dbResult.getData().get(i);
                                summary.append("  ").append(formatRowSummary(row)).append("\n");
                            }
                            if (dbResult.getData().size() > 3) {
                                summary.append("  ... (还有").append(dbResult.getData().size() - 3).append("条记录)\n");
                            }
                        }
                    }
                }
                case INSERT, UPDATE, DELETE -> {
                    summary.append("影响行数：").append(dbResult.getAffectedRows()).append("行\n");
                }
            }
        } else {
            summary.append("错误信息：").append(dbResult.getErrorMessage()).append("\n");
        }
        
        summary.append("执行时间：").append(dbResult.getExecutionTimeMs()).append("毫秒");
        
        return summary.toString();
    }

    /**
     * 格式化行摘要
     */
    private String formatRowSummary(Map<String, Object> row) {
        StringBuilder summary = new StringBuilder();
        
        // 优先显示常见字段
        String[] priorityFields = {"id", "username", "full_name", "email", "age", "status"};
        
        for (String field : priorityFields) {
            if (row.containsKey(field)) {
                if (summary.length() > 0) summary.append(", ");
                summary.append(field).append(": ").append(row.get(field));
            }
        }
        
        // 如果没有优先字段，显示前3个字段
        if (summary.length() == 0) {
            int count = 0;
            for (Map.Entry<String, Object> entry : row.entrySet()) {
                if (count > 0) summary.append(", ");
                summary.append(entry.getKey()).append(": ").append(entry.getValue());
                if (++count >= 3) break;
            }
        }
        
        return summary.toString();
    }

    /**
     * 获取操作描述
     */
    private String getOperationDescription(IntentDto.OperationType operation) {
        return switch (operation) {
            case SELECT -> "查询数据";
            case INSERT -> "插入数据";
            case UPDATE -> "更新数据";
            case DELETE -> "删除数据";
            case COUNT -> "统计数据";
            default -> "未知操作";
        };
    }

    /**
     * 获取默认响应消息
     */
    private String getDefaultResponseMessage(IntentDto.IntentResult intent, DatabaseOperationResult dbResult) {
        if (!dbResult.isSuccess()) {
            return "执行失败：" + dbResult.getErrorMessage();
        }
        
        return switch (intent.getOperation()) {
            case SELECT -> String.format("查询完成，找到 %d 条记录。", dbResult.getData() != null ? dbResult.getData().size() : 0);
            case INSERT -> String.format("成功插入 %d 条记录。", dbResult.getAffectedRows());
            case UPDATE -> String.format("成功更新 %d 条记录。", dbResult.getAffectedRows());
            case DELETE -> String.format("成功删除 %d 条记录。", dbResult.getAffectedRows());
            case COUNT -> "统计完成。";
            default -> "操作完成。";
        };
    }
}